package jmind.core.redis;

import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import jmind.core.algo.QuickLZ;
import jmind.core.util.SerializeUtil;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
import redis.clients.jedis.Pipeline;

/**
 * 简单redis实现
 * http://blog.csdn.net/telnetor/article/details/6704934
 * http://www.iteye.com/topic/1124415
 * @author weibo-xie
 * 2012-8-16
 */
public class SingleJedis extends AbstractJedis {

    private final JedisPool pool;

    public SingleJedis(String host, int timeout, int maxActive, int maxIdle) {
        String[] h = host.split(":");
        JedisPoolConfig config = new JedisPoolConfig();
        config.setMaxActive(maxActive);
        config.setMaxIdle(maxIdle);
        config.setMaxWait(1000L);
        config.setTestOnBorrow(true);
        pool = new JedisPool(config, h[0], Integer.parseInt(h[1]), timeout * 1000);
    }

    /******************string******************/
    /**
     * 删除key
     * @param keys
     */
    public long del(String... keys) {
        Jedis jedis = pool.getResource();
        try {
            return jedis.del(keys);
        } finally {
            close(jedis);
        }
    }

    public List<String> mget(String... keys) {
        Jedis jedis = pool.getResource();
        try {
            return jedis.mget(keys);
        } finally {
            close(jedis);
        }
    }

    public Long zaddKV(String key, Map<String, Double> memberScores) {
        Jedis jedis = getResource();
        try {
            Pipeline pipelined = jedis.pipelined();
            for (Entry<String, Double> entry : memberScores.entrySet()) {
                pipelined.zadd(key, entry.getValue(), entry.getKey());
            }
            pipelined.sync();
        } finally {
            close(jedis);
        }
        return 1l;
    }

    public boolean setObject(String key, Object o) {
        Jedis jedis = pool.getResource();
        try {
            byte[] byteArray = SerializeUtil.serialize(o);
            // 压缩
            byteArray = QuickLZ.compress(byteArray, 3);
            String setObjectRet = jedis.set(key.getBytes(), byteArray);
            return "OK".equalsIgnoreCase(setObjectRet);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            pool.returnResource(jedis);
        }
        return false;
    }

    @SuppressWarnings("unchecked")
    public <T> T getObject(String key, Class<T> clazz) {
        Jedis jedis = pool.getResource();
        Object o = null;
        try {
            byte[] bs = jedis.get(key.getBytes());
            // 解压
            bs = QuickLZ.decompress(bs);
            o = SerializeUtil.unserialize(bs);

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            pool.returnResource(jedis);
        }
        return (T) o;
    }

    public boolean ping() {
        Jedis jedis = null;
        try {
            jedis = pool.getResource();
            return "PONG".equalsIgnoreCase(jedis.ping());
        } catch (Exception e) {

        } finally {
            close(jedis);
        }
        return false;
    }

    //    @Override
    //    protected void finalize() throws Throwable {
    //        System.out.println(this.getClass().getName() + " finalize");
    //        pool.destroy();
    //        super.finalize();
    //    }

    @Override
    public Jedis getResource() {
        return pool.getResource();
    }

    @Override
    public void close(Object resource) {
        if (resource != null)
            pool.returnResourceObject(resource);

    }

    @Override
    public void releaseResource() {
        pool.destroy();

    }

}
